<?php
namespace app\attachment\controller;

use app\common\controller\Front;

class Index extends Front
{
    public function _initialize()
    {
        $this->request->filter('trim,strip_tags,htmlspecialchars');
        
        parent::_initialize();
    }
    
    //首页
    public function index()
    {
        $info = config('common.site_applys');
        return $info['markdown']['version'];
    }
    
    //按ID查询
    public function id()
    {
        //ID参数
        if(!$val = input('val/d',0)){
            $this->error(lang('mustIn'));
        }
        //查询数据
        $info = model('common/Info','loglic')->get([
            'cache'  => true,
            'status' => 'normal',
            'module' => 'attachment',
            'with'   => 'info_meta',
            'id'     => $val,
        ]);
        //公共入口
        $this->detail($info);
    }
    
    //按slug查询
    public function slug()
    {
        //ID参数
        if(!$val = input('val/s')){
            $this->error(lang('mustIn'));
        }
        //查询数据
        $info = model('common/Info','loglic')->get([
            'cache'  => true,
            'status' => 'normal',
            'module' => 'attachment',
            'with'   => 'info_meta',
            'slug'   => $val,
        ]);
        //公共入口
        $this->detail($info);
    }
    
    //按path查询
    public function path()
    {
        //ID参数
        if(!$val = input('val/s')){
            $this->error(lang('mustIn'));
        }
        //查询数据
        $info = model('common/Info','loglic')->get([
            'cache'   => true,
            'status'  => 'normal',
            'module'  => 'attachment',
            'with'    => 'info_meta',
            'excerpt' => $val,
        ]);
        //公共入口
        $this->detail($info);
    }
    
    //公用detail
    private function detail($info=[])
    {
        if(!$info){
            $this->error(lang('empty'));
        }
        if(!$info['info_mime_type']){
            $this->error(lang('attachment/error/mimeType'));
        }
        //附件不同状态（0=关闭；1=直接跳转；2=动态显示）
        if(config('common.attachment') == 1){
            //附件积分处理
            $this->scoreCheck($info['info_id'],$info['attachment_score']);
            //附件为绝对地址
            if(parse_url($info['info_excerpt'], PHP_URL_SCHEME)){
                $this->redirect($info['info_excerpt'], 302);
            }
            //附件为相对地址（本地上传）
            config('url_html_suffix',false);
            //是否CDN配置
            if(config('common.upload_cdn')){
                $this->redirect(trim(config('common.upload_cdn')).$info['info_excerpt'], 302);
            }else{
                $this->redirect($this->site['path_root'].trim(config('common.upload_path')).'/'.$info['info_excerpt'], 302);
            }
        }elseif(config('common.attachment') == 2){
            //附件积分处理
            $this->scoreCheck($info['info_id'],$info['attachment_score']);
            //附件为绝对地址
            if(parse_url($info['info_excerpt'], PHP_URL_SCHEME)){
                $this->curlBrowser($info['info_excerpt'], $info['info_mime_type'], $info['info_title']);
            }
            //附件为相对地址（本地上传）
            $filePath = trim(config('common.upload_path')).'/'.$info['info_excerpt'];
            //本地文件显示到浏览器
            if(file_exists($filePath)){
                $this->sendBrowser($filePath, $info['info_mime_type'], $info['info_title']);
            }
            //本地附件CDN配置
            if( config('common.upload_cdn') ){
                $this->curlBrowser(trim(config('common.upload_cdn')).$info['info_excerpt'], $info['info_mime_type'], $info['info_title']);
            }
            //找不到附件
            exit(lang('attachment/error/isDelete'));
        }else{
            exit(lang('off'));
        }
    }
    
    //发送本地文件到客户端
    private function sendBrowser($filePath='', $mimeType='image/png', $fileName='test.zip')
    {
        //浏览权限
        if(!is_readable($filePath)){
            $this->error(lang('attachment/error/isReadable'));
        }
        //HEADER
        header('Content-Type: '.$mimeType);//application/octet-stream
        header('Content-Length: '.filesize($filePath));
        //保存文件名
        if(substr($mimeType,0,5) != 'image'){
            header('Content-Disposition: attachment;filename = '.$fileName);//basename($file)
        }
        //读取文件
        exit(readfile($filePath));
    }
    
    //发送远程附件到浏览器
    private function curlBrowser($url='', $mimeType='image/png', $fileName='')
    {
        $ch = curl_init();
        curl_setopt ($ch, CURLOPT_URL, $url);
        curl_setopt ($ch, CURLOPT_HEADER, 0);
        curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1); 
        curl_setopt ($ch, CURLOPT_TIMEOUT, 10);
        curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT,10);
        curl_setopt ($ch, CURLOPT_FOLLOWLOCATION, 1);
        curl_setopt ($ch, CURLOPT_ENCODING, "");
        //https自动处理
        if(parse_url($url, PHP_URL_SCHEME) == 'https'){
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        }
        //获取到的内容
        $content = curl_exec($ch);
        //关闭链接
        curl_close($ch);
        //验证数据
        if(!$content){
            $this->error(lang('attachment/error/curlDown'));
        }
        //HEADER
        header('Content-Type: '.$mimeType);
        //保存文件名
        if(substr($mimeType,0,5) != 'image'){
            header('Content-Disposition: attachment;filename = '.DcEmpty($fileName, 'down'));
        }
        //显示内容
        exit($content);
    }
    
    /**
     * 附件积分处理
     * @param int $infoId 附件ID
     * @param int $infoScore 所需积分
     * @return obj 文件流
     */
    private function scoreCheck($infoId=0, $infoScore=0)
    {
        //积分处理开关
        if($infoScore < 1){
            return true;
        }
        //未安装USER插件
        if(!function_exists('userScoreDec')){
            $this->error(lang('attachment/error/system'));
        }
        //判断用户是否登录
        if( !$this->site['user']['user_id'] ){
            $this->error(lang('attachment/error/needLogin'), 'user/login/index');
        }
        //是否已经购买过了
        if( $this->getScoreLogs($infoId) ){
            return true;
        }
        //用户积分是否足够扣除本次请求
        if($infoScore > $this->site['user']['user_score']){
            $this->error(lang('attachment/error/scoreLess'), 'user/recharge/index');
        }
        //根据扣点设置扣除用户的积分
        if(!userScoreDec($this->site['user']['user_id'], $infoScore)){
            $this->error(lang('attachment/error/system'));
        }else{
            $this->setScoreLogs($infoId, $infoScore*-1);
        }
    }
    
    /**
     * 增加用户积分日志
     * @param int $logInfoId 附件ID
     * @param int $logValue 增减值
     * @return int 影响条数
     */
    private function setScoreLogs($logInfoId=0, $logValue=0)
    {
        $data = [];
        $data['log_name']     = 'attachment/index/score';
        $data['log_user_id']  = $this->site['user']['user_id'];
        $data['log_info_id']  = $logInfoId;
        $data['log_value']    = $logValue;
        $data['log_module']   = 'attachment';
        $data['log_controll'] = 'index';
        $data['log_action']   = 'score';
        $data['log_type']     = 'userScore';
        $data['log_ip']       = $this->request->ip();
        return model('common/Log','loglic')->save($data);
    }
    
    /**
     * 获取用户是否有积分支付记录
     * @param int $logInfoId 附件ID
     * @return int 影响条数
     */
    private function getScoreLogs($logInfoId=0)
    {
        $where = [
            'log_user_id'  => $this->site['user']['user_id'],
            'log_info_id'  => $logInfoId,
            'log_module'   => 'attachment',
            'log_controll' => 'index',
            'log_action'   => 'score',
            'log_type'     => 'userScore',
        ];
        return db('log')->where($where)->value('log_id');
    }
}